<?php
require_once(dirname(__FILE__) ."/Error.php");

/**
 *
 * Usage Example:
 * <code>
 * $file = new File();
 * if (!$file->catchPost($_FILES['myFile'])
 *  echo $file->getErrorMessage();
 * else
 * {
 *  $category->set(array('filename' => $file->filename));
 *  $category->update();
 * }
 * </code>
 */

class File extends Error
{
    public $file_title=""; // the real name of the file in db
    public $filename="";   // the name in the disk
    public $dirPath="";
    public $urlPath="";
    public $date_modified="";
    public $size=0;
    public $type='';
    public $handler;
    public $_errorMsg;
    // for handling posts
    public $postFilename;
    public $postTmpName;
    public $isTmp;

    public function load() {}

    public function open($mode = "r")
    {
        $this->handler = fopen($this->getPath(), $mode);
        return $this->handler;
    }

    public function eof()
    {
        return feof($this->handler);
    }

    // closes an open file pointer
    public function close()
    {
        return fclose($this->handler);
    }

    public function read($length)
    {
        if(!$this->handler)
            $this->open();
        return fread($this->handler, $length);
    }

    public function fileSize()
    {
        if($this->exists())
        return filesize($this->getPath());
    }

    // reads a single line from a file
    public function readLine()
    {
        while((($c = fgets($this->handler)) !== FALSE) && ($c != "\n"))
        {
            $str .= $c;
        }
        return $str;
    }

    public function buildpath(){}  // build a path from given parts array
    public function getTempDir(){}  // retrieves the system's temporary directory
    public function getTempFile(){}  // returns a path to a temporary file
    public function isAbsolute(){}  // checks wether the given path is an absolute path

    public function readAll(){}  // reads a complete file
    public function readChar(){}  // reads a single character from a file

    public function rewind(){}  // rewinds a file pointer
    public function skipRoot(){}  // strips the root directory from a given path
    public function stripLeadingSeparators(){}  // strip leading separators from a path
    public function stripTrailingSeparators(){}  // strips trailing separators from a path
    public function unlock(){}  // unlocks a locked file pointer
    public function write($str)
    {
        fwrite($this->handler, $str);
    }
    public function writeChar(){}  // writes a single character to a file

    public function writeLine($str) // writes a line to a file terminated by '\n'.
    {
        $str = $str[strlen($str) -1] == '\n' ? $str : $str.'\n';
        fwrite($this->handler, $str);
    }

    /*
        Expected array: $ar = $_FILES['userfile'];
        $ar['name']     // The original name of the file on the client machine.
        $ar['type']     // The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted.
        $ar['size']     // The size, in bytes, of the uploaded file.
        $ar['tmp_name'] //The temporary filename of the file in which the uploaded file was stored on the server.
        $ar['error']    //The error code associated with this file upload. This element was added in PHP 4.2.0
    */
    public function catchPost($post)
    {
        if ($post['error']==UPLOAD_ERR_OK)
        {
            $this->postDirName = ini_get('upload_tmp_dir');
            $this->postFilename = $post['name'];
            $this->postTmpName = $post['tmp_name'];
            $this->date_modified = date('Y-m-d h:i:s');
            $this->size = $post['size'];
            $this->type = $post['type'];
            $this->isTmp = true;
        }
        else
        {
            switch($post['error'])
            {
                case UPLOAD_ERR_INI_SIZE:   $msg = "S&oacute;lo puedes subir archivos de hasta ". ini_get('upload_max_filesize'); break;
                case UPLOAD_ERR_FORM_SIZE:  $msg = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form."; break;
                case UPLOAD_ERR_PARTIAL:    $msg = "The uploaded file was only partially uploaded."; break;
                case UPLOAD_ERR_NO_FILE:    $msg = "No has subido ning&uacute;n archivo."; break;
                case UPLOAD_ERR_NO_TMP_DIR: $msg = "Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3."; break;
                case UPLOAD_ERR_CANT_WRITE: $msg = "Failed to write file to disk. Introduced in PHP 5.1.0."; break;
                case UPLOAD_ERR_EXTENSION:  $msg = "File upload stopped by extension. Introduced in PHP 5.2.0."; break;
                default: $msg = "error!";
            }
            $this->_error($msg);
        }
        return $post['error'];
    }

    public function savePost($newPath='', $newFilename='', $createDirPath=true)
    {
        $newPath = $newPath? $newPath : $this->dirPath;
        $newFilename = $newFilename? $newFilename : $this->filename;
        if($createDirPath==true && !is_dir($newPath)) mkdir($newPath);
        if (move_uploaded_file($this->postTmpName, $newPath ."/". $newFilename))
        {
            $this->dirPath  = $newPath;
            $this->filename = $newFilename;
            $this->isTmp = false;
            $this->load();
            return 1;
        }
        $this->_error("error catching post");
        return 0;
    }

    public function getPath()
    {
        return $this->dirPath ."/". $this->filename;
    }

    public function getUrl()
    {
        return rtrim($this->urlPath ."/". $this->filename, "/");
    }

    public function exists()
    {
        return file_exists($this->getPath()) && !is_dir($this->getPath());
    }

    public function delete()
    {
        return (file_exists($this->getPath()) && unlink($this->getPath()))? 1 : 0;
    }

    public function getErrorMessage()
    {
        return $this->_errorMsg;
    }

    public function download()
    {
        if($this->exists())
        {
            $downloader = new Downloader($this->getPath(), $this->file_title );
            return $downloader->download();
        }
        else
        {
            $this->_error("No se encontr&oacute; el archivo");
            return 0;
        }
    }
}

?>
